package com.pipi.sso.core.service.impl;

import com.pipi.sso.core.enums.CommonStatusEnum;
import com.pipi.sso.core.enums.DormEnums;
import com.pipi.sso.core.enums.DormErrorCodeEnum;
import com.pipi.sso.core.exception.DormServiceException;
import com.pipi.sso.core.model.DormitoryAllocationBO;
import com.pipi.sso.core.model.DormitoryRoomBO;
import com.pipi.sso.core.model.StudentBO;
import com.pipi.sso.core.model.UserBO;
import com.pipi.sso.core.service.DormitoryAllocationService;
import com.pipi.sso.core.service.DormitoryRoomService;
import com.pipi.sso.core.service.StudentService;
import com.pipi.sso.core.service.UserService;
import com.pipi.sso.core.util.BeanUtils;
import com.pipi.sso.dao.manager.DormitoryAllocationManager;
import com.pipi.sso.dao.model.DormitoryAllocationDO;
import com.pipi.sso.dao.query.DormitoryAllocationQuery;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;
import java.util.Objects;

/**
 * All rights Reserved, Designed By www.maihaoche.com
 *
 * @Package com.pipi.sso.core.service.impl
 * @date: 2019/4/15 1:45 AM
 * @Copyright: 2017-2020 www.maihaoche.com Inc. All rights reserved.
 */
@Service
@Slf4j
public class DormitoryAllocationServiceImpl implements DormitoryAllocationService {

    @Resource
    private DormitoryAllocationManager dormitoryAllocationManager;

    @Resource
    private DormitoryRoomService dormitoryRoomService;

    @Resource
    private StudentService studentService;

    @Resource
    private UserService userService;

    @Override
    public void addByPerson(DormitoryAllocationBO dormitoryAllocationBO) {
        try {
            // 查询学生是否入住
            DormitoryAllocationQuery query = new DormitoryAllocationQuery();
            query.createCriteria().andIsDeletedEqualTo(CommonStatusEnum.NO.getCode()).
                    andStudentIdEqualTo(dormitoryAllocationBO.getStudentId());
            List<DormitoryAllocationDO> dormitoryAllocationDOS =
                    dormitoryAllocationManager.selectByQuery(query);
            if (CollectionUtils.isNotEmpty(dormitoryAllocationDOS)) {
                log.error("该学生已入住, studentId is {}", dormitoryAllocationBO.getStudentId());
                throw new DormServiceException(DormErrorCodeEnum.STUDENT_IS_CHECK_IN);
            }

            DormitoryAllocationDO dormitoryAllocationDO = BeanUtils.createCloneBean
                    (dormitoryAllocationBO, DormitoryAllocationDO.class);
            dormitoryAllocationDO.setIsDeleted(CommonStatusEnum.NO.getCode());
            // 查询房间名
            DormitoryRoomBO dormitoryRoomBO = new DormitoryRoomBO();
            dormitoryRoomBO.setDormitoryRoomId(dormitoryAllocationBO.getDormitoryRoomId());
            List<DormitoryRoomBO> dormitoryRoomBOS = dormitoryRoomService.queryNoPaged(dormitoryRoomBO);
            dormitoryRoomBO = dormitoryRoomBOS.get(0);
            dormitoryAllocationDO.setRoomName(dormitoryRoomBO.getRoomName());

            // 查询宿舍已入住人数
            DormitoryAllocationQuery dormitoryAllocationQuery = new DormitoryAllocationQuery();
            dormitoryAllocationQuery.createCriteria().andIsDeletedEqualTo(CommonStatusEnum.NO.getCode())
                    .andDormitoryRoomIdEqualTo(dormitoryAllocationBO.getDormitoryRoomId());
            int count = dormitoryAllocationManager.countByQuery(dormitoryAllocationQuery);
            if (count >= dormitoryRoomBO.getCapacity()) {
                log.error("该宿舍已住满, dormitoryRoomId is {}", dormitoryAllocationBO.getDormitoryRoomId());
                throw new DormServiceException(DormErrorCodeEnum.EXCEPTION.getErrCode(), "该宿舍人数已满");
            }
            dormitoryAllocationManager.insertSelective(dormitoryAllocationDO);

            // 入住成功后，为学生创建登陆账号
            StudentBO studentBO = new StudentBO();
            studentBO.setStudentId(dormitoryAllocationBO.getStudentId());
            List<StudentBO> studentBOS = studentService.queryStudent(studentBO);
            studentBO = studentBOS.get(0);

            UserBO userBO = new UserBO();
            userBO.setUsername(studentBO.getStudentNo());
            userBO.setPassword(studentBO.getStudentNo());
            userBO.setRoleId(DormEnums.RoleEnum.STUDENT.getId());
            userBO.setName(studentBO.getStudentName());
            userBO.setIsDeleted(CommonStatusEnum.NO.getCode());
            userBO.setStatus(CommonStatusEnum.YES.getCode());
            userService.addUser(userBO);

        } catch (DormServiceException e) {
            if (DormErrorCodeEnum.USER_IS_EXIST.getErrCode().equals(e.getCode())) {
                e.setMessage("该学生账号已经存在, 请核对账号信息");
            }
            throw e;
        } catch (Exception e) {
            log.error("按个人分配宿舍失败", e);
            throw new DormServiceException(DormErrorCodeEnum.EXCEPTION);
        }
    }

    @Override
    public void update(DormitoryAllocationBO dormitoryAllocationBO) {
        try {
            DormitoryAllocationQuery dormitoryAllocationQuery = buildQuery(dormitoryAllocationBO);

            DormitoryAllocationDO dormitoryAllocationDO = BeanUtils.createCloneBean(dormitoryAllocationBO, DormitoryAllocationDO.class);
            dormitoryAllocationManager.updateByQuerySelective(dormitoryAllocationDO, dormitoryAllocationQuery);
        } catch (Exception e) {
            log.error("退宿失败! ", e);
            throw new DormServiceException(DormErrorCodeEnum.EXCEPTION.getErrCode(), "退宿失败！");
        }
    }


    private DormitoryAllocationQuery buildQuery(DormitoryAllocationBO dormitoryAllocationBO) {
        DormitoryAllocationQuery query = new DormitoryAllocationQuery();
        DormitoryAllocationQuery.Criteria criteria = query.createCriteria().andIsDeletedEqualTo(CommonStatusEnum.NO.getCode());
        if (Objects.nonNull(dormitoryAllocationBO)) {
            if (Objects.nonNull(dormitoryAllocationBO.getDormitoryRoomId())) {
                criteria.andDormitoryRoomIdEqualTo(dormitoryAllocationBO.getDormitoryRoomId());
            }
            if (Objects.nonNull(dormitoryAllocationBO.getBuildingId())) {
                criteria.andBuildingIdEqualTo(dormitoryAllocationBO.getBuildingId());
            }
            if (Objects.nonNull(dormitoryAllocationBO.getStudentId())) {
                criteria.andStudentIdEqualTo(dormitoryAllocationBO.getStudentId());
            }
        }
        return query;
    }
}
